package com.vviton.zyhj.common.logger;

import java.lang.reflect.Method;
import java.util.Date;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import com.wdcloud.framework.core.log.LogInterface;
import com.wdcloud.framework.core.log.annotation.MonitorLog;
import com.wdcloud.framework.core.log.entity.MonitorLogInfo;

/**
 * 
 * ClassName: MonitorLogInterceptor <br/>
 * Function: MonitorLogInterceptor. <br/>
 * Date: 2016年3月10日 下午4:12:46 <br/>
 *
 * @author qiaocf
 * @version 1.0
 * @since JDK 1.7
 */
public class MonitorLogInterceptor implements MethodInterceptor {
    /** logInterface **/
    private LogInterface logInterface;

    /**
     * 
     * invoke,(呼叫). <br/>
     * Author: qiaocf <br/>
     * Create Date: 2016年3月10日 <br/>
     * =============================================================== <br/>
     * Modifier: qiaocf <br/>
     * Modify Date: 2016年3月10日 <br/>
     * Modify Description: <br/>
     * =============================================================== <br/>
     * 
     * @param invocation invocation
     * @return Object
     * @throws Throwable 异常
     * @since JDK 1.7
     */
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Method method = invocation.getMethod();
        MonitorLog logAnno = (MonitorLog) method.getAnnotation(MonitorLog.class);
        if (logAnno != null) {
            MonitorLogInfo monitorLogInfo = new MonitorLogInfo();

            Object returnObj = null;
            Long startTime = Long.valueOf(0L);
            Long endTime = Long.valueOf(0L);
            try {
                monitorLogInfo.setClasspath(invocation.getThis().getClass().getName());
                monitorLogInfo.setMethodName(method.getName());
                monitorLogInfo.setMethodParams(invocation.getArguments());
                monitorLogInfo.setText(logAnno.text());
                monitorLogInfo.setMethodType(logAnno.type());

                startTime = Long.valueOf(System.currentTimeMillis());
                returnObj = invocation.proceed();
                endTime = Long.valueOf(System.currentTimeMillis());

                monitorLogInfo.setStatus(true);
                if ("void".equals(method.getReturnType().getName())) {
                    monitorLogInfo.setReturnValue("void");
                } else {
                    monitorLogInfo.setReturnValue(returnObj);
                }
            } catch (Exception e) {
                endTime = Long.valueOf(System.currentTimeMillis());
                monitorLogInfo.setThrowable(e);
                monitorLogInfo.setStatus(false);
                throw e;
            } finally {
                monitorLogInfo.setStartTime(new Date(startTime.longValue()));
                monitorLogInfo.setEndTime(new Date(endTime.longValue()));
                monitorLogInfo.setExecuteTime(Long.valueOf(endTime.longValue() - startTime.longValue()));

                this.logInterface.updateMonitorLogInfo(monitorLogInfo, logAnno);
            }

            return returnObj;
        }
        return invocation.proceed();
    }

    public void setLogInterface(LogInterface logInterface) {
        this.logInterface = logInterface;
    }
}
